%option outfile="milexer.cpp"
%option noyywrap

%{
#include "midef.h"
#include "miparser.h"

#include <string>

static std::string	s_quoted_string;
static const char * s_input;
static const char * s_pos;

#define YY_INPUT(buf, result, max_size) \
    { \
    int c = * s_pos; \
    result = (c == '\0') ? YY_NULL : (buf[0] = c, ++s_pos, 1); \
    }
    
void InitLexer (const char * input);
%}

%x ESCAPE QUOTED

/*	regular definition	*/
ws			[\t ]+
digits		0|[1-9][0-9]*
variable	[^ \t\r\n+*=,{}~@^&\[\]\"]+

%%

{ws}				{	dbg_print (yytext);	}
\n					{	dbg_print ("nl\n");	return MI_NL;	}
\r\n				{	dbg_print ("nl\n");	return MI_NL;	}
<QUOTED>"\""		{	dbg_print ("[cstring end]"); BEGIN 0; yylval.strval = strdup (s_quoted_string.c_str ()); return MI_CSTRING;	}
"\""				{	dbg_print ("[cstring begin]"); BEGIN QUOTED; s_quoted_string.clear ();	}
<QUOTED>"\\"		{	dbg_print ("\\"); BEGIN ESCAPE;	s_quoted_string.push_back ('\\');	}
<QUOTED>[^\"\\]+	{	dbg_print (yytext); s_quoted_string += yytext;	}
<ESCAPE>.			{	dbg_print (yytext); BEGIN QUOTED;  s_quoted_string += yytext;	}
{digits}			{	dbg_print ("[token]"); yylval.intval = atoi (yytext); return MI_TOKEN;	}
"(gdb)"				{	dbg_print ("(gdb)"); return MI_GDB;	}
"done"				{	dbg_print ("done"); return MIC_DONE;		}
"running"			{	dbg_print ("running"); return MIC_RUNNING;	}
"connected"			{	dbg_print ("connected"); return MIC_CONNECTED;	}
"error"				{	dbg_print ("error"); return MIC_ERROR;	}
"exit"				{	dbg_print ("exit"); return MIC_EXIT;	}
"stopped"			{	dbg_print ("stopped"); return MIC_STOPPED;	}
{variable}			{	dbg_print ("[variable]"); dbg_print (yytext); yylval.strval = strdup (yytext); return MI_STRING;	}
.					{	dbg_print (yytext); return yytext[0];	}

%%

void InitLexer (const char * input)
{
	s_input = s_pos = input;
}
